import { sound} from "@pixi/sound";
import { SeStaticAudio } from "@/utils/Audio/SeStaticAudio.js";
export class SeAudio extends SeStaticAudio{
    constructor(parent,capacity=10){
        super(parent);
        this.capacity=capacity;
        this.soundObjects=[];
        this.willRemoved=[];
    }

    clear(){
        this.soundObjects.length=0;
        this.willRemoved.length=0;
        super.clear();
    }

    play(name){
        if(!name)return;
        let soundObject=this.soundsMap.get(name);
        if(!soundObject){
            this._load(name);
        }else{
            if(typeof soundObject == 'boolean'){
                this.loadPush('play',name);
                return;
            }
            if(soundObject.needRemove){
                soundObject.needRemove=false;
                let index=this.willRemoved.lastIndexOf(soundObject);
                if(index!=-1){
                    this.willRemoved.splice(index,1);
                }
            }
            this._onload(null,soundObject);
        }
        
    }

    stop(){
        super.stop();
        this.clearRemoved();
    }

    _onload=(err,soundObject)=>{
        soundObject.play(this.makePlayOptions());
        this.pushSoundObject(soundObject);
        this.loadCompleteCall();
    }
    _oncomplete=(soundObject)=>{
        if(!soundObject.isPlaying
            &&soundObject.needRemove){
            this.clearRemoved();
        }
    }

    pushSoundObject(soundObject){
        let index=this.soundObjects.indexOf(soundObject);
        let name=soundObject.options.name;
        if(index==-1){
            if(!this.soundsMap.has(name)){
                this.soundsMap.set(name,soundObject);
            }
        }else{
            this.soundObjects.splice(index,1);
        }
        this.soundObjects.push(soundObject);

        this.tryPopSoundObject();
    }

    tryPopSoundObject(){
        while(this.soundObjects.length>this.capacity){
            let soundObject=this.soundObjects.shift();
            if(soundObject.isPlaying){
                soundObject.needRemove=true;
                this.willRemoved.push(soundObject);
            }else{
                this.removeSoundObject(soundObject);
            }
        }
    }

    removeSoundObject(soundObject){
        this.soundsMap.delete(soundObject.options.name);
        sound.remove(`${soundObject.options.name}_se`);
    }

    clearRemoved(){
        if(this.willRemoved.length<=0)return;
        let insist=[];
        for(let soundObject of this.willRemoved){
            if(soundObject.isPlaying){
                insist.push(soundObject);
            }else{
                this.removeSoundObject(soundObject);
            }
        }

        this.willRemoved=insist;
    }

    makePlayOptions(opts){
        let options={
            volume:this.volume*this.mastervolume,
            speed:this._speed,
            complete:this._oncomplete,
            ...opts
        };

        if(this.filter){
            options.filters=[this.filter];
        }
        return options;
    }
}